package si2.robo;

import jason.environment.grid.Location;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import plplan.javaapi.EnumAlgorithm;
import plplan.javaapi.PLPlan;
import elements.GarbageGroup;

public class Aspirador {
	
	private int agentNumber;
	private String name;
	private int posX;
	private int posY;
	private boolean aspMovingUp;
	private boolean aspMovingLeft;
	private int type;
	private AspiradorModel model;
	
	private Integer coalitionID = -1;
	
	private HashMap<GarbageGroup, Double> utilityMap;
	private HashMap<Integer, Integer> typeMap;
	private PLPlan planner = null;
	
	private List plannerResults = null;
	
	private int lixosLocalizados = 0;
	private int lixosLimpos = 0;
	
	public Aspirador(int agentNumber, String name, int posInitialX, int posInitialY, boolean aspMovingUp, boolean aspMovingLeft, int type, AspiradorModel model) {
		this.agentNumber = agentNumber;
		this.name = name;
		this.aspMovingUp = aspMovingUp;
		this.aspMovingLeft = aspMovingLeft;
		this.type = type; //especialidade
		this.posX = posInitialX;
		this.posY = posInitialY;
		this.model = model;
		
		utilityMap = new HashMap<GarbageGroup, Double>();
		typeMap = new HashMap<Integer, Integer>();
		
		//Planner inits
		planner = new PLPlan();
		planner.setAlgorithm(EnumAlgorithm.GRAPHPLAN);
		
		plannerResults = new ArrayList();
		createOperators();		
	}
		
	public AspiradorModel getModel() {
		return model;
	}

	public void setModel(AspiradorModel model) {
		this.model = model;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setListaPlanos(List plannerResults) {
		this.plannerResults = plannerResults;
	}
	
	public List getListaPlanos() {
		return plannerResults;
	}
	
	public PLPlan getPlanner() {
		return planner;
	}
	
	public int getAgentNumber() {
		return agentNumber;
	}	

	public int getX() {
		
		return posX;
	}
	
	public void setX(int x) {
		this.posX = x;
		model.setAgPos(agentNumber, posX, posY);		
	}
	
	public int getY() {
		return posY;
	}
	
	public void setY(int y) {
		this.posY = y;
		model.setAgPos(agentNumber, posX, posY);
	}
	
	public int getType() {
		return type;
	}
	
	public void setType(int type) {
		this.type = type;
	}
	
	public void setPosition(Location l) {	
		this.posY = l.y;
		this.posX = l.x;
		model.setAgPos(agentNumber, l);
	}
	
	public void setPosition(int x, int y) {		
		this.posY = y;
		this.posX = x;
		model.setAgPos(agentNumber, posX, posY);
	}
	
	public Location getLocation() {
		return new Location(posX, posY);
	}

	public boolean isAspMovingUp() {
		return aspMovingUp;
	}

	public void setAspMovingUp(boolean aspMovingUp) {
		this.aspMovingUp = aspMovingUp;
	}

	public boolean isAspMovingLeft() {
		return aspMovingLeft;
	}

	public void setAspMovingLeft(boolean aspMovingLeft) {
		this.aspMovingLeft = aspMovingLeft;
	}
	
	public Map<GarbageGroup, Double> getUtilityMap() {
		return utilityMap;
	}

	public void setUtilityMap(HashMap<GarbageGroup, Double> utilityMap) {
		this.utilityMap = utilityMap;
	}
	
	public void setUtility(GarbageGroup garbageGroup, double utility){
		utilityMap.put(garbageGroup, utility);
	}
	
	public void addCoalitionID(Integer coalitionID) {
		this.coalitionID = coalitionID;
	}
	
	public void removeCoalitionID() {
		this.coalitionID = -1;
	}
	
	public Integer getCoalitionID() {
		return coalitionID;
	}
	
	public boolean hasCoalition() {
		if(coalitionID != -1) {
			return true;
		} 
		return false;
	}
	public void createOperators() {
		//Move right
		for(int i = 0; i< AspiradorEnvironment.TAMHGrid-1; i++){
			for(int j = 0; j< AspiradorEnvironment.TAMVGrid; j++){
				List<String> precond = new ArrayList<String>();
				precond.add("robot(" + i + "," + j + ")");
				List<String> rem = new ArrayList<String>();
				rem.add("robot(" + i + "," + j + ")");
				List<String> add = new ArrayList<String>();
				add.add("robot(" + (i+1) + "," + j + ")");
				planner.addOperator("move_right(" + i + "," + j + ";" + (i+1) + "," + j + ")", precond, rem, add);
			}
		}

		//Move left
		for(int i = 1; i< AspiradorEnvironment.TAMHGrid; i++){
			for(int j = 0; j< AspiradorEnvironment.TAMVGrid; j++){
				List<String> precond = new ArrayList<String>();
				precond.add("robot(" + i + "," + j + ")");
				List<String> rem = new ArrayList<String>();
				rem.add("robot(" + i + "," + j + ")");
				List<String> add = new ArrayList<String>();
				add.add("robot(" + (i-1) + "," + j + ")");
				planner.addOperator("move_left(" + i + "," + j + ";" + (i-1) + "," + j + ")", precond, rem, add);
			}
		}

		//Move down
		for(int i = 0; i< AspiradorEnvironment.TAMHGrid; i++){
			for(int j = 0; j< AspiradorEnvironment.TAMVGrid-1; j++){
				List<String> precond = new ArrayList<String>();
				precond.add("robot(" + i + "," + j + ")");
				List<String> rem = new ArrayList<String>();
				rem.add("robot(" + i + "," + j + ")");
				List<String> add = new ArrayList<String>();
				add.add("robot(" + i + "," + (j+1) + ")");
				planner.addOperator("move_down(" + i + "," + j + ";" + i + "," + (j+1) + ")", precond, rem, add);
			}
		}

		//Move up
		for(int i = 0; i< AspiradorEnvironment.TAMHGrid; i++){
			for(int j = 1; j< AspiradorEnvironment.TAMVGrid; j++){
				List<String> precond = new ArrayList<String>();
				precond.add("robot(" + i + "," + j + ")");
				List<String> rem = new ArrayList<String>();
				rem.add("robot(" + i + "," + j + ")");
				List<String> add = new ArrayList<String>();
				add.add("robot(" + i + "," + (j-1) + ")");
				planner.addOperator("move_up(" + i + "," + j + ";" + i + "," + (j-1) + ")", precond, rem, add);
			}
		}
	}
	
	public HashMap<Integer, Integer> getTypeMap() {
		return typeMap;
	}

	public void setTypeMap(HashMap<Integer, Integer> typeMap) {
		this.typeMap = typeMap;
	}
	
	public void setTypeMap(int type, int count) {
		typeMap.put(type, count);
	}
	
	public int getMainType(){
		int count = 0;
		int mainType = -1;
		for(int type : typeMap.keySet()){
			if(typeMap.get(type) >= count){
				count = typeMap.get(type);
				mainType = type;
			}
		}
		return mainType;
	}

	public int getLixosLocalizados() {
		return lixosLocalizados;
	}

	public void setLixosLocalizados(int lixosLocalizados) {
		this.lixosLocalizados = lixosLocalizados;
	}

	public int getLixosLimpos() {
		return lixosLimpos;
	}

	public void setLixosLimpos(int lixosLimpos) {
		this.lixosLimpos = lixosLimpos;
	}
}
